package com.jinly.ryder.database.dao;

import com.jinly.ryder.common.error.SystemErrorType;
import lombok.extern.slf4j.Slf4j;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class DbUtil {

    public static Connection initConnection(String url, String username, String password, String driverClassName) {
        Connection conn = null;
        try {
            Class.forName(driverClassName);
            conn = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            log.error("初始化数据库[{}]连接失败:{}", url, e.getMessage());
            SystemErrorType.INTERNAL_SERVER_ERROR.throwError("数据库连接失败");
        }
        return conn;
    }


    public static List<Map<String, Object>> executeQuerySql(Connection connection, String sql) {
        log.info("query:{}", sql);
        List<Map<String, Object>> list = new ArrayList<>();
        ResultSet rs = null;
        Statement statement = null;
        try {
            statement = connection.createStatement();
            rs = statement.executeQuery(sql);
            ResultSetMetaData metaData = rs.getMetaData();
            while (rs.next()) {
                Map<String, Object> row = new HashMap<>();
                for (int i = 1; i <= metaData.getColumnCount(); i++) {
                    row.put(metaData.getColumnLabel(i), rs.getObject(i));
                }
                list.add(row);
            }
        } catch (Exception e) {
            log.error("查询[{}]异常:{}", sql, e.getMessage());
            SystemErrorType.INTERNAL_SERVER_ERROR.throwError("数据库查询失败");
        } finally {
            close(rs);
            close(statement);
        }
        return list;
    }


    public static void close(AutoCloseable autoCloseable) {
        try {
            if (autoCloseable != null) {
                autoCloseable.close();
            }
        } catch (Exception e) {

        }
    }

    public static void execute(Connection connection, String sql) {
        log.info("execute:{}", sql);
        Statement statement = null;
        try {
            statement = connection.createStatement();
            statement.execute(sql);
        } catch (Exception e) {
            log.error("执行[{}]异常:{}", sql, e.getMessage());
            SystemErrorType.INTERNAL_SERVER_ERROR.throwError("数据库执行失败");
        } finally {
            close(statement);
        }
    }


    public static void batchInsert(Connection connection, String tableName, List<String> columnNameList, List<Map<String, Object>> dataList) {
        String insertSql = "replace into " + tableName + " (" + columnNameList.stream().collect(Collectors.joining(",")) + ")"
                + "values(" + columnNameList.stream().map(c -> "?").collect(Collectors.joining(",")) + ")";
        PreparedStatement statement = null;
        log.info("batchInsert:{},size:{}", insertSql, dataList.size());
        try {
            statement = connection.prepareStatement(insertSql);
            for (Map<String, Object> dataMap : dataList) {
                for (int i = 1; i <= columnNameList.size(); i++) {
                    statement.setObject(i, dataMap.get(columnNameList.get(i - 1)));
                }
                statement.addBatch();
            }
            statement.executeBatch();
        } catch (Exception e) {
            log.error("批量插入[{}]异常:{}", insertSql, e.getMessage());
            SystemErrorType.INTERNAL_SERVER_ERROR.throwError("数据库执行失败");
        } finally {
            close(statement);
        }
    }
}
